package org.sam.swing.table.verification;

import java.util.regex.Pattern;

/**
 * 正则表达式校验器 只接收String,null算校验合格
 * 
 * @author sam
 *
 */
public class PatternVerificatior extends AbstractVerificatior {

	/**
	 * 校验正则表达式
	 */
	private String regexp;

	/**
	 * 校验正则表达式
	 * 
	 * @return
	 */
	public String getRegexp() {
		return regexp;
	}

	/**
	 * 校验正则表达式
	 * 
	 * @param regexp
	 */
	public void setRegexp(String regexp) {
		this.regexp = regexp;
	}

	/**
	 * 可能的regexp标志
	 */
	private Flag[] flags;

	/**
	 * 可能的regexp标志
	 * 
	 * @return
	 */
	public Flag[] getFlags() {
		return flags;
	}

	/**
	 * 可能的regexp标志
	 * 
	 * @param flags
	 */
	public void setFlags(Flag[] flags) {
		this.flags = flags;
	}

	/**
	 * 正则表达式校验器 只接收String,null算校验合格
	 * 
	 * @param regexp
	 * @param flags
	 */
	public PatternVerificatior(String regexp, Flag... flags) {
		super();
		this.regexp = regexp;
		this.flags = flags;
	}

	/**
	 * 正则表达式校验器 只接收String,null算校验合格
	 * 
	 * @param regexp
	 * @param message
	 * @param flags
	 */
	public PatternVerificatior(String regexp, String message, Flag... flags) {
		super(message);
		this.regexp = regexp;
		this.flags = flags;
	}

	/**
	 * 正则表达式校验器 只接收String,null算校验合格
	 * 
	 * @param regexp
	 */
	public PatternVerificatior(String regexp) {
		super();
		this.regexp = regexp;
	}

	/**
	 * 正则表达式校验器 只接收String,null算校验合格
	 * 
	 * @param regexp
	 * @param message
	 */
	public PatternVerificatior(String regexp, String message) {
		super(message);
		this.regexp = regexp;
	}

	/**
	 * 缓存起来的正则表达式校验对象
	 */
	private Pattern pattern;

	/**
	 * 缓存起来的正则表达式校验对象
	 * 
	 * @return
	 */
	private Pattern getPattern() {
		if (pattern == null) {
			if (this.flags != null && this.flags.length > 0) {
				int flag = 0;
				for (Flag f : this.flags) {
					flag |= f.getValue();
				}
				pattern = Pattern.compile(regexp, flag);
			} else {
				pattern = Pattern.compile(regexp);
			}
		}
		return pattern;
	}

	/**
	 * {@inheritDoc} 通过jdk 正则表达式校验对象实现字段校验的功能
	 */
	@Override
	public boolean verificat(Object value) {
		if (value == null)
			return true;

		Pattern p = this.getPattern();
		return p.matcher(value.toString()).matches();
	}

	/**
	 * Possible Regexp flags
	 */
	public static enum Flag {

		/**
		 * Enables Unix lines mode
		 * 
		 * @see java.util.regex.Pattern#UNIX_LINES
		 */
		UNIX_LINES(java.util.regex.Pattern.UNIX_LINES),

		/**
		 * Enables case-insensitive matching
		 * 
		 * @see java.util.regex.Pattern#CASE_INSENSITIVE
		 */
		CASE_INSENSITIVE(java.util.regex.Pattern.CASE_INSENSITIVE),

		/**
		 * Permits whitespace and comments in pattern
		 * 
		 * @see java.util.regex.Pattern#COMMENTS
		 */
		COMMENTS(java.util.regex.Pattern.COMMENTS),

		/**
		 * Enables multiline mode
		 * 
		 * @see java.util.regex.Pattern#MULTILINE
		 */
		MULTILINE(java.util.regex.Pattern.MULTILINE),

		/**
		 * Enables dotall mode
		 * 
		 * @see java.util.regex.Pattern#DOTALL
		 */
		DOTALL(java.util.regex.Pattern.DOTALL),

		/**
		 * Enables Unicode-aware case folding
		 * 
		 * @see java.util.regex.Pattern#UNICODE_CASE
		 */
		UNICODE_CASE(java.util.regex.Pattern.UNICODE_CASE),

		/**
		 * Enables canonical equivalence
		 * 
		 * @see java.util.regex.Pattern#CANON_EQ
		 */
		CANON_EQ(java.util.regex.Pattern.CANON_EQ);

		// JDK flag value
		private final int value;

		private Flag(int value) {
			this.value = value;
		}

		/**
		 * @return flag value as defined in {@link java.util.regex.Pattern}
		 */
		public int getValue() {
			return value;
		}
	}
}
